package cn.stylefeng.guns.modular.gridsystem.controller;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.core.annotion.BusinessLog;
import cn.stylefeng.guns.core.enums.LogAnnotionOpTypeEnum;
import cn.stylefeng.guns.core.pojo.response.ResponseData;
import cn.stylefeng.guns.core.pojo.response.SuccessResponseData;
import cn.stylefeng.guns.modular.gridsystem.entity.*;
import cn.stylefeng.guns.modular.gridsystem.mapper.BizExceptionMapper;
import cn.stylefeng.guns.modular.gridsystem.model.result.DeviceStatusNumberResult;
import cn.stylefeng.guns.modular.gridsystem.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import cn.stylefeng.guns.modular.gridsystem.model.param.BizDeviceParam;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备表 控制器
 *
 * @author: ssy
 * @date: 2021/09/14 11:47
 */
@RestController
public class BizDeviceController {

    @Resource
    private BizGatewayService bizGatewayService;

    @Resource
    private BizStationService bizStationService;

    @Resource
    private BizGatewayChannelService bizGatewayChannelService;

    @Resource
    private BizDeviceService bizDeviceService;

    @Resource
    private BizGatewayTypeService bizGatewayTypeService;

    @Resource
    private BizExceptionMapper exceptionMapper;

    /**
     * 分页查询设备表
     *
     * @author ssy
     * @date 2021/09/14 11:47
     */
    @GetMapping("/bizDevice/page")
    @BusinessLog(title = "设备表_分页查询", opType = LogAnnotionOpTypeEnum.QUERY)
    public ResponseData page(BizDeviceParam bizDeviceParam) {
        return new SuccessResponseData(bizDeviceService.page(bizDeviceParam));
    }

    /**
     * 获取全部设备表
     *
     * @author ssy
     * @date 2021/09/14 11:47
     */
    @GetMapping("/bizDevice/list")
    @BusinessLog(title = "设备表_查询所有", opType = LogAnnotionOpTypeEnum.QUERY)
    public ResponseData list(BizDeviceParam bizDeviceParam) {
        return new SuccessResponseData(bizDeviceService.list(bizDeviceParam));
    }

    /**
     * 查看详情设备表
     *
     * @author ssy
     * @date 2021/09/14 11:47
     */
    @GetMapping("/bizDevice/detail")
    @BusinessLog(title = "设备表_查看详情", opType = LogAnnotionOpTypeEnum.DETAIL)
    public ResponseData detail(@Validated(BizDeviceParam.detail.class) BizDeviceParam bizDeviceParam) {
        return new SuccessResponseData(bizDeviceService.detail(bizDeviceParam));
    }

    /**
     * 添加设备表
     *
     * @author ssy
     * @date 2021/09/14 11:47
     */
    @PostMapping("/bizDevice/add")
    @BusinessLog(title = "设备表_增加", opType = LogAnnotionOpTypeEnum.ADD)
    public ResponseData add(@RequestBody @Validated(BizDeviceParam.add.class) BizDeviceParam bizDeviceParam) {
        bizDeviceService.add(bizDeviceParam);
        return new SuccessResponseData();
    }

    /**
     * 删除设备表
     *
     * @author ssy
     * @date 2021/09/14 11:47
     */
    @PostMapping("/bizDevice/delete")
    @BusinessLog(title = "设备表_删除", opType = LogAnnotionOpTypeEnum.DELETE)
    public ResponseData delete(@RequestBody @Validated(BizDeviceParam.delete.class) BizDeviceParam bizDeviceParam) {
        bizDeviceService.delete(bizDeviceParam);
        return new SuccessResponseData();
    }

    /**
     * 编辑设备表
     *
     * @author ssy
     * @date 2021/09/14 11:47
     */
    @PostMapping("/bizDevice/edit")
    @BusinessLog(title = "设备表_编辑", opType = LogAnnotionOpTypeEnum.EDIT)
    public ResponseData edit(@RequestBody @Validated(BizDeviceParam.edit.class) BizDeviceParam bizDeviceParam) {
        bizDeviceService.edit(bizDeviceParam);
        return new SuccessResponseData();
    }

    /**
     * 根据当前用户查询电站和设备数量
     *
     * @param stationIds
     * @return
     */
    @GetMapping("/bizDevice/getCountByStationIds")
    public ResponseData getCountByStationIds(String stationIds) {
        final String[] split = stationIds.split(",");
        int count = 0;
        for (String stationId : split) {
            final LambdaQueryWrapper<BizDevice> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BizDevice::getStationId, stationId);
            count += bizDeviceService.count(queryWrapper);
        }
        return new SuccessResponseData(count);
    }

    /**
     * 查询设备列表
     *
     * @param stationId
     * @return
     */
    @GetMapping("/bizDevice/getAllListById")
    public Map<String, Object> getAllListByStationId(Integer stationId) {
        LambdaQueryWrapper<BizDevice> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BizDevice::getStationId, stationId);
        BizStation bizStation = bizStationService.getById(stationId);
        Map<String, Object> hashMap = MapUtil.newHashMap();
        hashMap.put("stationId", bizStation.getId());
        hashMap.put("stationName", bizStation.getStationName());
        hashMap.put("stationAddress", bizStation.getStationAddress());


        // todo 查询设备在线离线数量
        DeviceStatusNumberResult deviceOnlineNumber = bizGatewayService.getDeviceOnlineNumber(stationId);
        if(ObjectUtil.isNotNull(deviceOnlineNumber)){
            hashMap.put("onlineNumber", deviceOnlineNumber.getOnlineNumber());
            hashMap.put("offlineNumber", deviceOnlineNumber.getOfflineNumber());
        }

        List<BizDevice> deviceList = bizDeviceService.list(queryWrapper);
        Map<Object, Object> deviceMap = MapUtil.newHashMap();
        for (BizDevice device : deviceList) {
            List<String> gatewayCodes = new ArrayList<>();
            Integer deviceId = device.getId();
            String deviceName = device.getDeviceName();
            LambdaQueryWrapper<BizGatewayChannel> channelQueryWrapper = new LambdaQueryWrapper<>();
            channelQueryWrapper.eq(BizGatewayChannel::getDeviceId, deviceId);
            List<BizGatewayChannel> channelList = bizGatewayChannelService.list(channelQueryWrapper);
            List<Map<String, Object>> mapList = new ArrayList<>();
            Set<Map<String, Object>> gateways = new HashSet<>();
            for (BizGatewayChannel gatewayChannel : channelList) {
                Integer gatewayId = gatewayChannel.getGatewayId();
                QueryWrapper<BizGateway> gatewayQueryWrapper = new QueryWrapper<>();
                gatewayQueryWrapper.select("id as gatewayId", "type_code as typeCode", "gateway_code as gatewayCode", "gateway_name as gatewayName");
                gatewayQueryWrapper.eq("id", gatewayId);
                Map<String, Object> gateway = bizGatewayService.getMap(gatewayQueryWrapper);
                if (ObjectUtil.isNotNull(gateway)) {
                    QueryWrapper<BizGatewayType> queryWrapper1 = new QueryWrapper<>();
                    queryWrapper1.eq("code", gateway.get("typeCode"));
                    BizGatewayType bizGatewayType = bizGatewayTypeService.getOne(queryWrapper1);
                    if (ObjectUtil.isNotNull(bizGatewayType)) {
                        gateway.put("fileName", bizGatewayType.getFileName());
                    }
                    gateways.add(gateway);
                }
                Map<String, Object> channelMap = new LinkedHashMap<>();
                channelMap.put("name", gateway.get("gatewayCode"));
                channelMap.put("micRouter", gatewayChannel.getChannel());
                channelMap.put("installLocation", gatewayChannel.getInstallLocation());
                mapList.add(channelMap);
            }
            HashMap<Object, Object> gatewayMap = MapUtil.newHashMap();
            gatewayMap.put("deviceName", deviceName);
            gatewayMap.put("deviceId", deviceId);
            gatewayMap.put("deviceFileName", device.getFileName());
            gatewayMap.put("gateway", gateways);
            gatewayMap.put("count", gateways.size());

            for (Map<String, Object> g : gateways) {
                gatewayCodes.add(g.get("gatewayCode").toString());
            }
            /*mapList.sort((o1, o2) -> {
                if (o1.get("name").equals(o2.get("name"))) {
                    if (Integer.valueOf(o1.get("micRouter").toString()) > Integer.valueOf(o2.get("micRouter").toString())) {
                        return 1;
                    }
                }
                return -1;
            });*/
            gatewayMap.put("channel", mapList);
            if (ObjectUtil.isNotEmpty(gatewayCodes)) {
                gatewayMap.put("hasNoHandleException", exceptionMapper.selectCount(new LambdaQueryWrapper<BizException>()
                        .in(BizException::getGatewayCode, gatewayCodes)
                        .eq(BizException::getStatus, "0")) > 0);
            } else {
                gatewayMap.put("hasNoHandleException", false);
            }
            deviceMap.put(deviceId, gatewayMap);
        }
        hashMap.put("device", deviceMap);
        return hashMap;
    }
}
